import { RuntimeError, RuntimeModelError } from '@ibiz-template/core';
import {
  INavViewMsg,
  ITreeController,
  ITreeEvent,
  ITreeExpBarController,
  ITreeExpBarEvent,
  ITreeExpBarState,
  ITreeNodeData,
} from '@ibiz-template/runtime';
import { IDETree, IDETreeNode, ITreeExpBar } from '@ibiz/model-core';
import { ExpBarControlController } from '../exp-bar.controller';

/**
 * 树导航栏控制器
 *
 * @export
 * @class TreeExpBarController
 * @extends {ExpBarControlController<ITreeExpBar, ITreeExpBarState, ITreeExpBarEvent>}
 * @implements {ITreeExpBarController}
 */
export class TreeExpBarController
  extends ExpBarControlController<
    ITreeExpBar,
    ITreeExpBarState,
    ITreeExpBarEvent
  >
  implements ITreeExpBarController
{
  /**
   * 默认展开节点集合
   * @author lxm
   * @date 2023-08-08 05:35:12
   * @type {string[]}
   */
  defaultExpandedKeys?: string[];

  get xDataController(): ITreeController {
    const controller = this.view.getController(this.model.xdataControlName!);
    if (!controller) {
      throw new RuntimeModelError(
        this.model,
        `无法获取多数据部件[${this.model.xdataControlName}]控制器`,
      );
    }
    return controller as ITreeController;
  }

  /**
   * 导航栏key
   *
   * @author zk
   * @date 2023-07-10 03:07:11
   * @memberof TreeExpBarController
   */
  navKeyName = 'id' as const;

  /**
   * 有导航视图的节点模型标识集合
   * @author lxm
   * @date 2023-08-10 06:33:14
   * @type {string[]}
   */
  navNodeModelIds: string[] = [];

  /**
   * 获取指定节点模型
   *
   * @param {string} nodeId
   * @return {*}  {(IDETreeNode | undefined)}
   * @memberof TreeExpBarController
   */
  getNodeModel(nodeId: string): IDETreeNode | undefined {
    const { detreeNodes } = this.XDataModel as IDETree;
    let nodeModel: IDETreeNode | undefined;
    if (detreeNodes) {
      detreeNodes.forEach(node => {
        if (node.id === nodeId) {
          nodeModel = node;
        }
      });
    }
    return nodeModel;
  }

  /**
   * 多数据激活
   *
   * @author zk
   * @date 2023-05-29 03:05:36
   * @param {IData} data
   * @memberof ExpBarControlController
   */
  xDataActive(event: ITreeEvent['onActive']['event']): void {
    const { nodeData } = event;
    // 树导航处理onActive使用树节点数据
    super.xDataActive({ ...event, data: [nodeData] });
  }

  /**
   *  获取导航视图
   *
   * @author zk
   * @date 2023-06-29 03:06:41
   * @param {IDETabViewPanel} tabViewPanel
   * @return {*}  {Promise<INavViewMsg>}
   * @memberof TabExpPanelController
   */
  public getNavViewMsg(
    node: ITreeNodeData,
    context: IContext,
    params: IParams,
  ): INavViewMsg {
    const nodeId = node.id;
    const deData = node.deData || node;
    const nodeModel = this.getNodeModel(node.nodeId);
    if (!nodeModel) {
      throw new RuntimeError(`找不到${node.nodeId}的节点模型`);
    }
    const result = this.prepareParams(nodeModel, [deData], context, params);
    result.context.currentSrfNav = nodeId;
    return {
      key: nodeId,
      viewId: nodeModel.navAppViewId,
      ...result,
    };
  }

  protected defaultNavByFirstItem(): void {
    const data = this.xDataController.state.items.find(node =>
      this.navNodeModelIds.includes(node.nodeId),
    );
    if (!data) {
      return;
    }
    // 默认选中并激活第一项
    this.xDataController.setActive(data);
    this.xDataController.setSelection([data]);
  }

  protected async onCreated(): Promise<void> {
    await super.onCreated();

    // 初始化带导航的节点标识ids
    const { detreeNodes } = this.XDataModel as IDETree;
    detreeNodes?.forEach(node => {
      if (node.navAppViewId) {
        this.navNodeModelIds.push(node.id!);
      }
    });

    // 计算树的默认展开集合
    if (this.state.srfnav) {
      const expandedKeys: string[] = [];
      this.state.srfnav.split(':').forEach((item, index) => {
        if (index === 0) {
          expandedKeys.push(item);
        } else {
          expandedKeys.push(`${expandedKeys[index - 1]}:${item}`);
        }
      });
      expandedKeys.pop(); // 删除最后一个
      this.defaultExpandedKeys = expandedKeys;
    }
  }
}
